package top.duduwy.service;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import top.duduwy.model.RegionStats;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

@Service
public class DataService implements InitializingBean {

    @Value("${covid19_confirmed_global_csv_url}")
    private String covid19_confirmed_global_csv_url;

    /**
     * 爬取全球冠状病毒实时统计数据的csv文件
     * @param url
     * @return
     */
    public Resource getCsv(String url) {
        RequestEntity<Void> requestEntity = RequestEntity
                .get(URI.create(url))
                .headers(httpHeaders -> httpHeaders.add("User-Agent", "Du"))
                .build();
        ResponseEntity<Resource> exchange = new RestTemplate().exchange(requestEntity, Resource.class);
        Resource body = exchange.getBody();

        return body;
    }

    /**
     * 每天凌晨1点执行计划任务，更新allRegionStats成员变量
     *
     * @return
     * @throws IOException
     */
    @Scheduled(cron = "${Schedules.updateVirusDataCron}")
    public List<RegionStats> fetchAllData() throws IOException {
        List<RegionStats> list = new ArrayList<>();
        //使用Apache Commons CSV组件解释CSV文件。
        Reader in = new InputStreamReader(getCsv(covid19_confirmed_global_csv_url).getInputStream());
        Iterable<CSVRecord> records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
        for (CSVRecord record : records) {
            RegionStats regionStats = new RegionStats();
            regionStats.setState(record.get("Province/State"));
            regionStats.setCountry(record.get("Country/Region"));
            int latestTotalCases = Integer.parseInt(record.get(record.size() - 1));
            regionStats.setLatestTotalCases(latestTotalCases);
            int pre = Integer.parseInt(record.get(record.size() - 2));
            int diffFromPrevDay = latestTotalCases - pre;
            regionStats.setDifFromPrevDay(diffFromPrevDay);
            list.add(regionStats);
        }
        return list;
    }

    /**
     * 初始化bean时，若bean实现了InitializingBean接口，会自动调用afterPropertiesSet方法
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        fetchAllData();
    }
}

